package com.zzh.lib.manager;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;

import com.zzh.lib.core.lang.HStrUtils;
import com.zzh.lib.core.utils.LogUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Date: 2020/7/17 15:58
 * @Email: zzh_hz@126.com
 * @QQ: 1299234582
 * @Author: zzh
 * @Description: activity 管理类
 */
public class HAppManager {
    private static HAppManager sInstance;

    private Application mApplication;
    private final List<Activity> mActivityHolder = new CopyOnWriteArrayList<>();

    private boolean mIsDebug;

    private HAppManager() {
    }

    public static HAppManager getInstance() {
        if (sInstance == null) {
            synchronized (HAppManager.class) {
                if (sInstance == null)
                    sInstance = new HAppManager();
            }
        }
        return sInstance;
    }

    public void setDebug(boolean debug) {
        mIsDebug = debug;
    }

    public synchronized void init(Application application) {
        if (mApplication == null) {
            mApplication = application;
            mApplication.registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks);
        }
    }

    private final Application.ActivityLifecycleCallbacks mActivityLifecycleCallbacks = new Application.ActivityLifecycleCallbacks() {
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            addActivity(activity);
        }

        @Override
        public void onActivityStarted(Activity activity) {
        }

        @Override
        public void onActivityResumed(Activity activity) {
            final int index = mActivityHolder.indexOf(activity);
            if (index < 0)
                return;

            final int size = mActivityHolder.size();
            if (size <= 1)
                return;

            if (index != (size - 1)) {
                if (mIsDebug)
                    Log.e(HAppManager.class.getSimpleName(), "start order activity " + activity + " old index " + index);

                removeActivity(activity);
                addActivity(activity);

                if (mIsDebug)
                    Log.e(HAppManager.class.getSimpleName(), "end order activity " + activity + " new index " + mActivityHolder.indexOf(activity));
            }
        }

        @Override
        public void onActivityPaused(Activity activity) {
        }

        @Override
        public void onActivityStopped(Activity activity) {
        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        }

        @Override
        public void onActivityDestroyed(Activity activity) {
            removeActivity(activity);
        }
    };

    private String getCurrentStack() {
        Object[] arrActivity = mActivityHolder.toArray();
        return Arrays.toString(arrActivity);
    }

    /**
     * 添加对象
     *
     * @param activity
     */
    public void addActivity(Activity activity) {
        if (mActivityHolder.contains(activity))
            return;

        mActivityHolder.add(activity);

        if (mIsDebug) {
            String s = HAppManager.class.getSimpleName() + "+++++ " + activity + " " + mActivityHolder.size()
                    + "\r\n" + getCurrentStack();
            LogUtils.d(s);
        }
    }

    /**
     * 移除对象
     *
     * @param activity
     */
    public void removeActivity(Activity activity) {
        if (mActivityHolder.remove(activity)) {
            if (mIsDebug) {
                Log.e(HAppManager.class.getSimpleName(), "----- " + activity + " " + mActivityHolder.size()
                        + "\r\n" + getCurrentStack());
            }
        }
    }

    /**
     * 返回栈中保存的对象个数
     *
     * @return
     */
    public int size() {
        return mActivityHolder.size();
    }

    /**
     * 返回栈中指定位置的对象
     *
     * @param index
     * @return
     */
    public Activity getActivity(int index) {
        try {
            return mActivityHolder.get(index);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 返回栈中最后一个对象
     *
     * @return
     */
    public Activity getLastActivity() {
        return getActivity(mActivityHolder.size() - 1);
    }

    /**
     * 是否包含指定对象
     *
     * @param activity
     * @return
     */
    public boolean containsActivity(Activity activity) {
        return mActivityHolder.contains(activity);
    }

    /**
     * 返回栈中指定类型的所有对象
     *
     * @param clazz
     * @return
     */
    public List<Activity> getActivity(Class<? extends Activity> clazz) {
        final List<Activity> list = new ArrayList<>(1);
        for (Activity item : mActivityHolder) {
            if (item.getClass() == clazz)
                list.add(item);
        }
        return list;
    }

    /**
     * 返回栈中指定类型的第一个对象
     *
     * @param clazz
     * @return
     */
    public Activity getFirstActivity(Class<? extends Activity> clazz) {
        for (Activity item : mActivityHolder) {
            if (item.getClass() == clazz)
                return item;
        }
        return null;
    }

    /**
     * 栈中是否包含指定类型的对象
     *
     * @param clazz
     * @return
     */
    public boolean containsActivity(Class<? extends Activity> clazz) {
        return getFirstActivity(clazz) != null;
    }

    /**
     * 栈中是否包含指定类型的对象
     *
     * @param canonicalName clz.getCanonicalName()
     * @return true or false
     */
    public boolean containsActivity(String canonicalName) {
        return getActivity(canonicalName) != null;
    }

    /**
     * 结束栈中指定类型的对象
     *
     * @param clazz
     */
    public void finishActivity(Class<? extends Activity> clazz) {
        final List<Activity> list = getActivity(clazz);
        for (Activity item : list) {
            item.finish();
        }
    }

    public void finishActivity(String canonicalName) {
        final List<Activity> list = getActivityList(canonicalName);
        if (list.isEmpty()) {
            return;
        }
        for (Activity item : list) {
            item.finish();
        }
    }

    /**
     * 结束栈中除了activity外的所有对象
     *
     * @param activity
     */
    public void finishActivityExcept(Activity activity) {
        for (Activity item : mActivityHolder) {
            if (item != activity)
                item.finish();
        }
    }

    /**
     * 结束栈中除了指定类型外的所有对象
     *
     * @param clazz
     */
    public void finishActivityExcept(Class<? extends Activity> clazz) {
        for (Activity item : mActivityHolder) {
            if (item.getClass() != clazz)
                item.finish();
        }
    }

    /**
     * 结束栈中除了activity外的所有activity类型的对象
     *
     * @param activity
     */
    public void finishSameClassActivityExcept(Activity activity) {
        for (Activity item : mActivityHolder) {
            if (item.getClass() == activity.getClass()) {
                if (item != activity)
                    item.finish();
            }
        }
    }

    /**
     * 结束所有对象
     */
    public void finishAllActivity() {
        for (Activity item : mActivityHolder) {
            item.finish();
        }
    }

    /**
     * 获取activity实例
     *
     * @param canonicalName clz.getCanonicalName 。
     * @return 为空则没有此对象
     */
    public Activity getActivity(String canonicalName) {
        for (Activity item : mActivityHolder) {
            if (HStrUtils.equals(item.getClass().getCanonicalName(), canonicalName)) {
                return item;
            }
        }
        return null;
    }

    public List<Activity> getActivityList(String name) {
        List<Activity> list = new ArrayList<>();
        for (Activity item : mActivityHolder) {
            if (HStrUtils.equals(item.getClass().getCanonicalName(), name)) {
                list.add(item);
            }
        }
        return list;
    }

    /**
     * 注意有可能会返回null
     *
     * @param canonicalName clz.getCanonicalName()
     * @return 返回查找出来的第一个对象。
     */
    public Optional<Activity> getFirstActivity(String canonicalName) {
        for (Activity item : mActivityHolder) {
            if (HStrUtils.equals(item.getClass().getCanonicalName(), canonicalName)) {
                return Optional.of(item);
            }
        }
        return Optional.empty();
    }

    /**
     * 获取第一个对象
     *
     * @param simpleName 类的simpleName
     * @return 返回查找出来的第一个对象，为空则没有此对象
     */
    public Optional<Activity> getFirstActivityBySimpleName(String simpleName) {
        for (Activity item : mActivityHolder) {
            if (HStrUtils.equals(item.getClass().getSimpleName(), simpleName)) {
                return Optional.of(item);
            }
        }
        return Optional.empty();
    }

    public final List<Activity> getActivityHolder() {
        return mActivityHolder;
    }
}